// Copyright (c) 2009 Hypirinha contributers
// This program is made available under the terms of the MIT License.
package org.hypirinha.html.codegen;

import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.hypirinha.html.codegen.CompilationUnit.LICENCE;

import java.io.PrintStream;
import java.io.ByteArrayOutputStream;

public class GeneratedInterfaceTest {
    
    @Test
    public void shouldProvideRelativePathIncludingPackageNameAndClassName() {
        CompilationUnit generatedInterface = new GeneratedInterface("org.hypirinha.html.elements", "Html");

        assertEquals("org/hypirinha/html/elements/Html.java", generatedInterface.getFileName());
    }

    @Test
    public void shouldPrintPackageNameAtTheTopOfTheFile() {
        CompilationUnit generatedInterface = new GeneratedInterface("org.hypirinha.html.elements", "Html");

        assertTrue(print(generatedInterface).startsWith(LICENCE + "package org.hypirinha.html.elements;\n"));
    }

    @Test
    public void shouldPrintImports() {
        CompilationUnit generatedInterface = new GeneratedInterface("org.hypirinha.html.elements", "Html");

        generatedInterface.addImport("org.hypirinha.html.elements.contents.*");

        assertTrue(print(generatedInterface).contains("\n\nimport org.hypirinha.html.elements.contents.*;\n"));
    }

    @Test
    public void shouldIncludeInterfaceDeclaration() {
        CompilationUnit generatedInterface = new GeneratedInterface("org.hypirinha.html.elements", "Html");

        assertTrue(print(generatedInterface).contains("public interface Html {\n"));
        assertTrue(print(generatedInterface).endsWith("}\n"));
    }

    @Test
    public void shouldIncludeSuperInterface() {
        GeneratedInterface generatedInterface = new GeneratedInterface("org.hypirinha.html.elements", "Body");

        generatedInterface.addBaseInterface("HtmlContent");
        assertTrue(print(generatedInterface).contains("public interface Body extends HtmlContent {\n"));
    }

    @Test
    public void shouldIncludeMultipleSuperInterfaces() {
        GeneratedInterface generatedInterface = new GeneratedInterface("org.hypirinha.html.elements", "Tr");

        generatedInterface.addBaseInterface("TableContent");
        generatedInterface.addBaseInterface("TbodyContent");
        assertTrue(print(generatedInterface).contains("public interface Tr extends TableContent, TbodyContent {\n"));
    }

    @Test
    public void shouldIncludeMembers() {
        CompilationUnit generatedInterface = new GeneratedInterface("org.hypirinha.html.elements", "Html");

        generatedInterface.getMembers().add(new Member() {
            public void printTo(PrintStream printStream) {
                printStream.println("This is a member");
            }
        });

        assertTrue(print(generatedInterface).endsWith("{\nThis is a member\n}\n"));
    }

    @Test
    public void shouldSplitLongListOfSuperInterfacesOverMultipleLines() {
        GeneratedInterface generatedInterface = new GeneratedInterface("org.hypirinha.html.elements", "Div");

        for (int i = 0; i < 100; i++) {
            generatedInterface.addBaseInterface("interface" + i);
        }

        String[] lines = print(generatedInterface).split("\n");

        for (String line : lines) {
            assertTrue(line.length() <= CodegenUtil.TARGET_LINE_WIDTH);
        }
    }
    
    private String print(CompilationUnit generatedInterface) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        generatedInterface.printTo(new PrintStream(outputStream));
        return new String(outputStream.toByteArray());
    }
}
